/**
 * @typedef {object} ControlsOption
 * @property {import('three').PerspectiveCamera} camera
 * @property {import('three').Scene} scene
 * @property {import('three').WebGLRenderer} [renderer]
 * @property {import('three').Object3D[]} [objects]
 * @property {HTMLCanvasElement} [canvas]
 */
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
import { Raycaster, Vector2 } from 'three';
/**
 * @description 处理点击事件
 * @param {MouseEvent} event
 */
function _getClickObject(event) {
  const { camera, raycaster, objects } = this;
  event.preventDefault();
  const mouse = new Vector2(
    (event.offsetX / event.target.clientWidth) * 2 - 1,

    -(event.offsetY / event.target.clientHeight) * 2 + 1
  );
  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObjects(objects);
  // TODO: 点击函数要支持自定义
  // TODO: 支持多mesh的ancestors点击
  // 维护objects 过滤controls
  let selectObject = null;
  if (intersects.length > 0) {
    const { parent, ancestors } = intersects[0].object;
    if (parent && parent.type === 'Group') {
      selectObject = parent;
    } else {
      selectObject = intersects[0].object;
    }
  }
  return selectObject;
}

/**
 * TODO:
 *  - ⭐ 设计一套完善的objects维护逻辑
 *  - 在初始化controls后，在新增物体时，需要重新设置dragControls的objects
 *  - 在可编辑object被拖动时，外层的基座需要变换透明度
 *  - MARK: 方案选择：固定视角切换 + transformControl 控制(2D)
 */
export default class Controls {
  /**
   * @type {OrbitControls | null}
   */
  orbitControls = null;

  /**
   * @type {TransformControls | null}
   */
  transformControls = null;

  /**
   * @type {ControlsOption}
   */
  option = {};
  /**
   * @param {ControlsOption} option
   */
  constructor(option) {
    this.option = option;
    this.initOribitControls();
    this.initTransformControls();
  }

  initOribitControls() {
    const { camera, renderer, scene } = this.option;
    this.orbitControls = new OrbitControls(camera, renderer.domElement);
    renderer.render(scene, camera);
  }

  /**
   * @description 依赖orbitControls
   */
  initTransformControls() {
    // TODO: 后续修改
    const { camera, renderer, scene, objects } = this.option;
    const transformControls = new TransformControls(camera, renderer.domElement);

    transformControls.addEventListener('mouseDown', (event) => {
      console.log('鼠标按下', event);
      this.orbitControls.enabled = false;
    });
    transformControls.addEventListener('objectChange', () => {
      console.log('物体变化');
      renderer.render(scene, camera);
    });
    transformControls.addEventListener('mouseUp', () => {
      console.log('鼠标抬起');
      this.orbitControls.enabled = true;
      renderer.render(scene, camera);
    });

    scene.add(transformControls);
    this.transformControls = transformControls;

    const box = renderer.domElement;
    const raycaster = new Raycaster();
    // TODO：需要正确取消监听
    box.addEventListener('click', (event) => {
      const selectObject = _getClickObject.bind({
        camera,
        raycaster,
        objects,
      })(event);
      if (selectObject) {
        transformControls.attach(selectObject);
      } else {
        transformControls.detach();
      }
    });
    // TODO: 右键菜单
    box.addEventListener('contextmenu', (event) => {
      const selectObject = _getClickObject.bind({
        camera,
        raycaster,
        objects,
      })(event);
      if (selectObject) {
        // 生成一个简易的菜单
        const div = document.createElement('div');
      } else {
      }
    });
  }
  destroy() {
    this.orbitControls && this.orbitControls.dispose();
    this.transformControls && this.transformControls.dispose();
  }
}
